package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.system.domain.SysMenu;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysRoleMenu;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.domain.params.SysMenuParams;
import com.ruoyi.system.domain.params.SysRoleParams;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysRoleMenuMapper;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysRoleMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 角色 业务层处理
 *
 * @author ruoyi
 */
@Service
@Slf4j
public class SysRoleMenuServiceImpl implements ISysRoleMenuService {

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private SysRoleMenuMapper roleMenuMapper;

    @Autowired
    private ISysMenuService sysMenuService;

    @Override
    public Set<Long> selectRoleBottomMenu(Long deptId, String roleKey,List<String> projectCodes) {
        List<Long> deptIds = sysDeptService.selectDeptAncestors(deptId);
        deptIds.add(deptId);
        Set<Long> sysRoleMenuSet = getRoleMenu(deptIds, roleKey,projectCodes, true);
        return sysRoleMenuSet;
    }

    @Override
    public List<SysRoleMenu> getDiffRoleMenu(Long deptId, String roleKey, Long[] menuIds,List<String> projectCodes) {
        List<Long> menuIdList = new ArrayList<>();
        for (Long menuId : menuIds) {
            menuIdList.add(menuId);
        }
        return getDiffRoleMenu(deptId, roleKey, menuIdList,projectCodes);
    }

    /**
     * 获取包含自己的角色菜单
     *
     * @param deptId
     * @param roleKey
     * @return
     */
    @Override
    public Set<Long> getRoleMenuContainSelf(Long deptId, String roleKey,List<String> projectCodes) {
        List<Long> deptIds = sysDeptService.selectDeptAncestors(deptId);
        deptIds.add(deptId);
        return getRoleMenu(deptIds, roleKey,projectCodes);
    }

    /**
     * 获取排除自己的角色菜单
     *
     * @param deptId
     * @param roleKey
     * @return
     */
    @Override
    public Set<Long> getRoleMenuExcludeSelf(Long deptId, String roleKey,List<String> projectCodes) {
        List<Long> deptIds = sysDeptService.selectDeptAncestors(deptId);
        return getRoleMenu(deptIds, roleKey,projectCodes);
    }

    @Override
    public Set<Long> getRoleMenu(List<Long> deptIds, String roleKey,List<String> projectCodes) {
        return getRoleMenu(deptIds, roleKey,projectCodes, false);
    }

    /**
     * @param deptIds
     * @param roleKey
     * @param isOnlyBottomMenu 是否获取仅仅底层的菜单
     * @return
     */
    @Override
    public Set<Long> getRoleMenu(List<Long> deptIds, String roleKey,List<String> projectCodes, Boolean isOnlyBottomMenu) {
        isOnlyBottomMenu = isOnlyBottomMenu == null ? false : isOnlyBottomMenu;
        Set<Long> sysRoleMenuSet = new HashSet<>();
        if (deptIds.size() > 0) {
            SysRoleParams sysRoleParams = new SysRoleParams();
            sysRoleParams.setDeptIds(deptIds);
            sysRoleParams.setRoleKey(roleKey);
//            sysRoleParams.setDelFlag("0");
//            sysRoleParams.setStatus("0");
//            sysRoleParams.setStatus("0");
            Page<SysRole> page = new Page<>(1, -1);
            List<SysRole> sysRoleList = roleMapper.selectRoleList(page,sysRoleParams).getRecords();
            Map<String, SysRole> sysRoleMap = new HashMap<>();
            for (SysRole sysRole : sysRoleList) {
                //需要添加删除状态作为唯一标识 否则可能会拿到删除的数据  后设计数据只有一条 如果存在删除的就激活
                sysRoleMap.put(sysRole.getDeptId() + "_" + sysRole.getRoleKey(), sysRole);
            }
//            Map<Long,SysRoleMenu> sysRoleMenuMap = new HashMap<>();
            for (Long deptIdTemp : deptIds) {
                SysRole sysRole = sysRoleMap.get(deptIdTemp + "_" + roleKey);
                if (sysRole != null) {
                    //判断当没有删除并且状态没有停用并且允许继承的
                    if (!"2".equals(sysRole.getDelFlag()) &&
                            !"1".equals(sysRole.getStatus()) &&
                            !"N".equals(sysRole.getIsAllowExtends())) {
//                    roleIds.add(sysRole.getRoleId());
                        SysRoleMenu roleMenuParam = new SysRoleMenu();
                        roleMenuParam.setRoleId(sysRole.getRoleId());
                        roleMenuParam.setProjectCodes(projectCodes);
                        List<SysRoleMenu> roleMenuList;
//                        if(isOnlyBottomMenu){
                        roleMenuList = roleMenuMapper.selectRoleMenuList(roleMenuParam);
/*                        }else{
                            roleMenuList = roleMenuMapper.selectRoleMenuBottomList(roleMenuParam);
                        }*/
                        for (SysRoleMenu sysRoleMenuTemp : roleMenuList) {
                            //判断是否为例外当不是例外的时候 添加 当为例外的是删除
                            if (sysRoleMenuTemp.getIsException().equals("N")) {
                                sysRoleMenuSet.add(sysRoleMenuTemp.getMenuId());
                            } else {
                                sysRoleMenuSet.remove(sysRoleMenuTemp.getMenuId());
                            }
                        }
                    }
                }
            }
        }

        if (isOnlyBottomMenu) {
//            menuSer
            sysRoleMenuSet = sysMenuService.rejectParentMenu(sysRoleMenuSet);
        }
        //
        return sysRoleMenuSet;
    }

    @Override
    public List<SysRoleMenu> getDiffRoleMenu(Long deptId, String roleKey, List<Long> menuIdList,List<String> projectCodes) {
        //获取所有父级别的菜单
        Set<Long> sysRoleMenuSet = getRoleMenuExcludeSelf(deptId, roleKey,projectCodes);
        List<SysMenu> sysMenusMem =new ArrayList<>();
        Map<Long,SysMenu> sysMenuMemMap = new HashMap<>();

        Set<String>  sysRoleMenuMemSet = new HashSet<>();
        if(sysRoleMenuSet!=null) {
            sysRoleMenuSet.forEach((menuId) -> {
                sysRoleMenuMemSet.add(menuId+"");
            });
        }

        if(menuIdList!=null){
            menuIdList.forEach((menuId)->{
                sysRoleMenuMemSet.add(menuId+"");
            });
        }

        if(sysRoleMenuMemSet!=null&&!sysRoleMenuMemSet.isEmpty()) {
            SysMenuParams menu = new SysMenuParams();
            String menuIdsStr = String.join(",", sysRoleMenuMemSet);
            menu.setMenuIdsStr(menuIdsStr);
            sysMenusMem = sysMenuService.selectMenuList(menu);
            sysMenusMem.forEach((SysMenu)->{
                sysMenuMemMap.put(SysMenu.getMenuId(),SysMenu);
            });
        }

        //sysRoleMenuSet 与 menuIds进行对比
        //为了不影响原始数据
        List<Long> menuIdListTemp = new ArrayList<>();
        menuIdListTemp.addAll(menuIdList);

        // 新增用户与角色管理

        for (int i = 0; i < menuIdListTemp.size(); i++) {
            Long menuId = menuIdListTemp.get(i);
            //当存在的时候相互抵消
            if (sysRoleMenuSet.contains(menuId)) {
                menuIdListTemp.remove(i);
                sysRoleMenuSet.remove(menuId);
                i--;
            }
        }
        List<SysRoleMenu> list = new ArrayList<SysRoleMenu>();
        //当子级存在而父级 加入为非例外
        for (int i = 0; i < menuIdListTemp.size(); i++) {
            Long menuId = menuIdListTemp.get(i);
            SysMenu sysMenu = sysMenuMemMap.get(menuId);
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenu.setIsException("N");
            sysRoleMenu.setProjectCode(sysMenu.getProjectCode());
            list.add(sysRoleMenu);
        }

        //当父级存在而子级不存在的时候 加入列外
        for (Long menuId : sysRoleMenuSet) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            SysMenu sysMenu = sysMenuMemMap.get(menuId);
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenu.setIsException("Y");
            sysRoleMenu.setProjectCode(sysMenu.getProjectCode());
            list.add(sysRoleMenu);
        }
        return list;
    }
}
